/**
 * <strong>Title : BOMController.java<br>
 * </strong> <strong>Package : cn.b.sky.mes.cm.controller<br>
 * </strong> <strong>Description : </strong>@类注释说明写在此处@<br>
 * <strong>Create on : 2016年1月18日 下午1:31:10<br>
 * </strong>
 * <p>
 * @author dapeng.li<br>
 * @version <strong>v1.0.0</strong><br>
 * <br>
 *          <strong>修改历史:</strong><br>
 *          修改人 | 修改日期 | 修改描述<br>
 *          -------------------------------------------<br>
 * <br>
 * <br>
 */
package cn.b.sky.mes.cm.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.b.sky.mes.cm.model.BOM;
import cn.b.sky.mes.cm.model.BOMComponent;
import cn.b.sky.mes.cm.model.Material;
import cn.b.sky.mes.cm.model.condition.BOMCondition;
import cn.b.sky.mes.cm.service.BOMService;
import cn.b.sky.mes.cm.service.MaterialService;
import cn.b.sky.common.constants.SystemConstant;
import cn.b.sky.common.model.BatchJobReport;
import cn.b.sky.common.model.DWZResult;
import cn.b.sky.user.controller.SecurityController;

import com.alibaba.fastjson.JSONObject;

/**
 * <strong>Title : BOMController.java<br></strong>
 * <strong>Package : cn.b.sky.mes.cm.controller<br></strong>
 * <strong>Description : </strong>BOM控制器<br> 
 * <strong>Create on : 2016年1月18日 下午1:31:10<br></strong>
 * <p>
 * @author dapeng.li<br>
 * @version <strong>v1.0.0</strong><br>
 * <br>
 * <strong>修改历史:</strong><br>
 * 修改人 | 修改日期 | 修改描述<br>
 * -------------------------------------------<br>
 * <br>
 * <br>
 */

@Controller
@RequestMapping("/bom/*")
public class BOMController extends SecurityController {

  @Resource
  BOMService bomService;

  @Resource
  MaterialService materialService;

  @RequestMapping("bomList")
  public String selectBOMListByCondition(Model model, String navTabId,
      @ModelAttribute("condition") BOMCondition condition) {
    condition.setSiteCode(getSiteCode());
    List<BOM> list = bomService.selectBOMListByCondition(condition);
    int count = bomService.selectBOMCountByCondition(condition);
    condition.setData(list);
    condition.setTotalCount(count);
    model.addAttribute("page", condition);
    model.addAttribute(NAVTABID, navTabId);
    return "cm/bom/bomList";

  }

  @RequestMapping("addBOM")
  public String addBom(Model model, String navTabId) {
    model.addAttribute(NAVTABID, navTabId);
    return "cm/bom/bom_add";
  }

  @RequestMapping("editBOM")
  public String editBOM(Model model, String navTabId, String id) {
    BOM bom = bomService.getBOMAndComponents(id, getSiteCode());
    List<String> materialCodes = new ArrayList<String>();
    List<Material> list = bomService.selectMaterialByBomCode(bom.getBomCode(), bom.getSiteCode());
    bomService.recurseMaterials(materialCodes, list);
    model.addAttribute("bom", bom);
    model.addAttribute("disabledMaterialCodes", JSONObject.toJSONString(materialCodes));
    model.addAttribute(NAVTABID, navTabId);
    return "cm/bom/bom_edit";
  }

  @RequestMapping("viewBOM")
  public String viewBOM(Model model, String navTabId, String id) {
    BOM bom = bomService.getBOMAndComponents(id, getSiteCode());
    List<BOMComponent> components = bomService.selectComponentsAndItsBomCode(bom.getBomCode(), getSiteCode());
    this.recurseChildComponents(components);

    bom.setComponents(components);
    model.addAttribute("bom", bom);
    model.addAttribute(NAVTABID, navTabId);
    return "cm/bom/bom_view";
  }

  @RequestMapping("saveBOM")
  @ResponseBody
  public DWZResult saveBOM(Model model, String navTabId, String id, BOM bom) {
    if (bom == null) {
      return ajaxError(getImeViewMessageI18n(null, SystemConstant.PARAMETERNULL));
    }
    if (bom.getLockFlag() == null) {
      bom.setLockFlag(0);
    }
    setCreateInfo(bom);
    bom.setSiteCode(getSiteCode());
    if (StringUtils.isBlank(id)) {
      bomService.insertBOM(bom);
    } else {
      boolean success = bomService.updateBOM(bom);
      if (!success) {
        return ajaxError(getImeViewMessageI18n(null, "componentAddError.M"));
      }
    }
    return dialogAjaxDone(getImeViewMessageI18n(null, "successfulOperation.M"), navTabId, null, null, null);
  }

  @RequestMapping("deleteBOM")
  @ResponseBody
  public DWZResult deleteBOM(Model model, String navTabId, HttpServletRequest request) {

    String ids = request.getParameter("ids");
    if (StringUtils.isBlank(ids)) {
      return ajaxError(getImeViewMessageI18n(null, SystemConstant.PARAMETERNULL));
    }
    String[] codes = ids.split(",");
    int len = codes.length;
    BatchJobReport[] reports = new BatchJobReport[len];
    boolean success = true;
    for (int i = 0; i < len; i++) {
      reports[i] = bomService.deleteBOM(codes[i], getSiteCode());
      if (!reports[i].isSuccess()) {
        success = false;
      }
    }
    if (success) {
      return navTabAjaxDone(navTabId, null, null, null, getImeViewMessageI18n(null, "successfulOperation.M"), null);
    } else {
      return batchjobAjaxDone(request, Arrays.asList(reports));
    }
  }

  @RequestMapping("bomLookUp")
  public String bomLookUp(Model model, String lookupType, @ModelAttribute("condition") BOMCondition condition) {
    condition.setSiteCode(getSiteCode());
    condition.setLockFlag(0);
    List<BOM> list = bomService.selectBOMListByCondition(condition);
    int count = bomService.selectBOMCountByCondition(condition);
    condition.setData(list);
    condition.setTotalCount(count);
    model.addAttribute("page", condition);
    return "cm/bom/bom_lookup";

  }

  @RequestMapping("bomSuggest")
  @ResponseBody
  public Object bomSuggest(@ModelAttribute("condition") BOMCondition condition) {
    condition.setSiteCode(this.getSiteCode());
    condition.setLockFlag(0);
    return bomService.selectBOMSuggests(condition);
  }

  @RequestMapping(value = "validateBomCodeForSelect")
  @ResponseBody
  public boolean validateBomCodeForSelect(String bomCode) {

    if (!StringUtils.isEmpty(bomCode)) {
      BOM bom = bomService.getBOM(bomCode, getSiteCode());
      return bom != null && bom.getLockFlag() == 0;
    }
    return false;
  }

  @RequestMapping(value = "checkBomCode")
  @ResponseBody
  public boolean checkBomCodeNotExists(String bomCode) {
    if (!StringUtils.isEmpty(bomCode)) {
      return null == bomService.getBOM(bomCode, getSiteCode());
    }
    return true;
  }

  @RequestMapping(value = "getChildrenList")
  @ResponseBody
  public DWZResult getChildrenList(String bomCode) {
    if (!StringUtils.isEmpty(bomCode)) {
      List<BOMComponent> components = bomService.selectComponentsAndItsBomCode(bomCode, getSiteCode());
      this.recurseChildComponents(components);
      return ajaxDone(components);
    }
    return null;
  }

  private void recurseChildComponents(List<BOMComponent> components) {
    for (BOMComponent component : components) {
      if (component.getQuantity() == 0d) {
        component.setQuantity(1d);
      }
      if (!StringUtils.isBlank(component.getChildBomCode())) {
        List<BOMComponent> children = bomService.selectComponentsAndItsBomCode(component.getChildBomCode(),
            getSiteCode());
        for (BOMComponent child : children) {
          // 需要的数量为 每个父组件需要的个数 * 父组件的个数
          child.setQuantity(child.getQuantity() * component.getQuantity());
        }
        component.setChildComponents(children);
        recurseChildComponents(children);
      }
    }
  }

  @RequestMapping("positive")
  public String selectPositiveBOMList(Model model, String navTabId) {
    model.addAttribute(NAVTABID, navTabId);
    return "cm/bom/positiveList";
  }

  @RequestMapping("positiveList")
  @ResponseBody
  public List<BOMComponent> selectPositiveBOMList(String materialCode) {
    if (StringUtils.isEmpty(materialCode)) {
      return new ArrayList<BOMComponent>();
    }
    List<BOMComponent> components = new ArrayList<BOMComponent>();
    Material material = materialService.selectMaterial(getSiteCode(), materialCode);
    if (null == material) {
      return new ArrayList<BOMComponent>();
    }
    BOMComponent bc = new BOMComponent(material);
    if (!StringUtils.isEmpty(material.getBomCode())) {
      BOM bom = bomService.getBOMAndComponents(material.getBomCode(), getSiteCode());
      List<BOMComponent> list = bomService.selectComponentsAndItsBomCode(bom.getBomCode(), getSiteCode());
      this.recurseChildComponents(list);
      bc.setChildComponents(list);
    }
    components.add(bc);
    return components;
  }

  @RequestMapping("reversed")
  public String reversedPage(Model model, String navTabId) {
    model.addAttribute(NAVTABID, navTabId);
    return "cm/bom/reversedList";
  }

  @RequestMapping("reversedList")
  @ResponseBody
  public List<BOMComponent> selectReversedBOMList(String materialCode) {
    if (StringUtils.isEmpty(materialCode)) {
      return new ArrayList<BOMComponent>();
    }
    List<BOMComponent> components = new ArrayList<BOMComponent>();
    Material material = materialService.selectMaterial(getSiteCode(), materialCode);
    if (null == material) {
      return new ArrayList<BOMComponent>();
    }
    BOMComponent bc = new BOMComponent(material);
    List<BOMComponent> list = bomService.selectParentsComponents(bc.getComponentCode(), getSiteCode());
    this.recurseParentComponents(list);
    bc.setChildComponents(list);
    components.add(bc);
    return components;
  }

  private void recurseParentComponents(List<BOMComponent> components) {
    for (BOMComponent component : components) {
      if (!StringUtils.isEmpty(component.getComponentCode())) {
        List<BOMComponent> children = bomService.selectParentsComponents(component.getComponentCode(),
            getSiteCode());
        component.setChildComponents(children);
        recurseParentComponents(children);
      }
    }
  }

}
